#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <sys/wait.h>



int main(void)

{

    //父进程在自己的栈上声明的局部变量

    int count = 1;

    //初始化子进程的PID

    pid_t childpid;

    
    //fork创建子进程,相当于分配了一块新的内存空间,然后把父进程的数据都拷贝进去
    childpid = fork(); /* child duplicates parent’s address space */
    
    
    //系统程序要习惯检查系统的调用情况
    if (childpid < 0) {

        perror("fork()");

        return EXIT_FAILURE;

    }

    else /* fork() returns 2 values: 0 for child pro and childpid for parent pro 
        通过打印出子进程和父进程的PID,fork相当于告诉了父进程创建了一个子进程,它的childpid就为子进程的PID；
        在子进程环境中,它没有子进程,所以childpid就是0
    */

        if (childpid == 0) { /* This is child pro */

            printf("[Children] childpid = %d \n",childpid);

            //在子进程的栈空间上进行的操作时不会改变父进程的栈内的数据的

            count++;

            int data = 1;

            printf("Child pro pid = %d, count = %d (addr = %p),data= %d (addr = %p)\n", getpid(), count, &count,data,&data); 

        }

        else { /* This is parent pro */

            printf("[Parent] childpid = %d \n",childpid);

            //在子进程的栈空间上进行的操作时不会改变父进程的栈内的数据的
            int data = 3;

            printf("Parent pro pid = %d, child pid = %d, count = %d (addr = %p),data= %d (addr = %p)\n", getpid(), childpid, count, &count,data,&data);

            sleep(5);

            /*有可能有不止一个子进程,所以必须等到所有子进程结束后再继续。
            子进程结束之后操作系统会回收除了Process Table(存储进程状态)所有的资源,之后父进程wait()检查这个表,确保所有的子进程都结束了之后才会继续执行
            */
            wait(0); /* waiting for all children terminated */

        }

    //一定是父进程先达到testing point
    printf("Testing point by %d\n", getpid()); /* child executed this statement and became defunct before parent wait() */

    return EXIT_SUCCESS;

}

